﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Reflection;
using Unknown.Framework.Configuration;
using Unknown.Framework.Develop;

namespace Unknown.Framework.Injection
{
    /// <summary>
    /// 对象配置处理类
    /// </summary>
    public class ObjectConfigurationHandler : AbstractConfigurationHandler<Collection<ObjectConfiguration>>
    {
        private Dictionary<string, ObjectIdentify> _Dictionary = new Dictionary<string, ObjectIdentify>();
        /// <summary>
        /// 字典
        /// </summary>
        public Dictionary<string, ObjectIdentify> Dictionary
        {
            get
            {
                return this._Dictionary;
            }
        }

        /// <summary>
        /// 匹配字符串
        /// </summary>
        protected override string SearchPattern
        {
            get
            {
                return ".Injection.xml";
            }
        }
        /// <summary>
        /// 示例值
        /// </summary>
        protected override Collection<ObjectConfiguration> ExampleValue
        {
            get
            {
                Collection<ObjectConfiguration> results = new Collection<ObjectConfiguration>();

                ObjectConfiguration objectConfiguration = new ObjectConfiguration();
                Type type = this.GetType();
                objectConfiguration.Name = type.FullName;
                objectConfiguration.Scope = type.Assembly.FullName;
                objectConfiguration.Target = type.FullName;

                results.Add(objectConfiguration);

                return results;
            }
        }

        /// <summary>
        /// 解析
        /// </summary>
        /// <param name="value">数据</param>
        protected override void Resolve(Collection<ObjectConfiguration> value)
        {
            if (value != null)
            {
                foreach (ObjectConfiguration objectConfiguration in value)
                {
                    bool register = this.Dictionary.ContainsKey(objectConfiguration.Name);
                    if (!register)
                    {
                        Assembly assembly = null;
                        Type type = null;

                        try
                        {
                            assembly = Assembly.Load(objectConfiguration.Scope);
                            if (assembly != null)
                            {
                                type = assembly.GetType(objectConfiguration.Target);
                            }
                        }
                        catch (ArgumentNullException exception)
                        {
                            Collection<string> remarks = new Collection<string>();
                            remarks.Add(objectConfiguration.Name);
                            remarks.Add(objectConfiguration.Scope);
                            remarks.Add(objectConfiguration.Target);

                            CrashHandlers.Default.Hibernate(exception, remarks);
                        }
                        catch (ArgumentException exception)
                        {
                            Collection<string> remarks = new Collection<string>();
                            remarks.Add(objectConfiguration.Name);
                            remarks.Add(objectConfiguration.Scope);
                            remarks.Add(objectConfiguration.Target);

                            CrashHandlers.Default.Hibernate(exception, remarks);
                        }
                        catch (BadImageFormatException exception)
                        {
                            Collection<string> remarks = new Collection<string>();
                            remarks.Add(objectConfiguration.Name);
                            remarks.Add(objectConfiguration.Scope);
                            remarks.Add(objectConfiguration.Target);

                            CrashHandlers.Default.Hibernate(exception, remarks);
                        }
                        catch (FileLoadException exception)
                        {
                            Collection<string> remarks = new Collection<string>();
                            remarks.Add(objectConfiguration.Name);
                            remarks.Add(objectConfiguration.Scope);
                            remarks.Add(objectConfiguration.Target);

                            CrashHandlers.Default.Hibernate(exception, remarks);
                        }
                        catch (FileNotFoundException exception)
                        {
                            Collection<string> remarks = new Collection<string>();
                            remarks.Add(objectConfiguration.Name);
                            remarks.Add(objectConfiguration.Scope);
                            remarks.Add(objectConfiguration.Target);

                            CrashHandlers.Default.Hibernate(exception, remarks);
                        }

                        if ((assembly != null) && (type != null))
                        {
                            ObjectIdentify objectIdentify = new ObjectIdentify();

                            objectIdentify.Scope = assembly;
                            objectIdentify.Target = type;

                            this.Dictionary.Add(objectConfiguration.Name, objectIdentify);
                        }
                    }
                }
            }
        }
    }
}
